package com.binarycube.webserver.datasource;

import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;

import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;

import org.apache.log4j.Logger;

import com.binarycube.webserver.config.DatasourceConfig;

public class LDAPDataSource extends AbstractDataSource implements IDataSource{
	static Logger log = Logger.getLogger(LDAPDataSource.class.getName());
	
	String host;
	String port;
	String base;
	Hashtable<String, String> env;
	
	public List<Record> doQuery() {
		try {
	        LdapContext ctx = new InitialLdapContext(env, null);
	        ctx.setRequestControls(null);
	        NamingEnumeration<?> namingEnum = ctx.search(base, _config.getProperty("query"), getSimpleSearchControls());
	        while (namingEnum.hasMore ()) {
	            SearchResult result = (SearchResult) namingEnum.next ();    
	            Attributes attrs = result.getAttributes ();
	            if (attrs != null) {
	            	Record r = Record.MappedRecord();
	            	Enumeration<?> attrEnum = attrs.getAll();
	            	while (attrEnum.hasMoreElements()) {
	            		Attribute attrib = (Attribute) attrEnum.nextElement();
	            		r.put(attrib.getID(), attrib.get());
	            	}
	            	
	            	_records.add(r);
	            	
	            }
	           

	        } 
	        namingEnum.close();
	    } catch (Exception e) {
	    	log.error("Error querying LDAP Datasource: " + _config.getName(), e);
	    }

		return _records;
	}
	

	
	public void configure(DatasourceConfig config) {
		super.configure(config);
		
		host = _config.getProperty("host");
		port = _config.getProperty("port");
		base = _config.getProperty("base");
		
		env = new Hashtable<String, String>();
	    env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
	    env.put(Context.PROVIDER_URL, "ldap://" + host + ":" + port  );
	    //env.put(Context.SECURITY_AUTHENTICATION, "none");
	    env.put(Context.SECURITY_PRINCIPAL,_config.getProperty("bindDN"));//DN
	    env.put(Context.SECURITY_CREDENTIALS,_config.getProperty("bindPassword"));//This is password
	  
		
	}


	private SearchControls getSimpleSearchControls() {
	    SearchControls searchControls = new SearchControls();
	    searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
	    searchControls.setTimeLimit(30000);
	    //String[] attrIDs = {"objectGUID"};
	    //searchControls.setReturningAttributes(attrIDs);
	    return searchControls;
	}

}
